import { App } from "../../../src/App";
import { Singleton } from "../../../src/core/Class";

/**
 * 红点类型
 */
enum RedPointType{
    unknow = -1,
    default,    // 普通红点只做提示
    number,     // 红点+数字，一般做邮件提醒，提示有多少未读邮件
    max
}

interface Item{
    target:cc.Node,
    redImg:cc.Node,
    lblNum:cc.Label,
    redType:RedPointType,
    bindProtol:string[],
}

class CRedPointSys extends Singleton<CRedPointSys>{
    private _texture2d:cc.Texture2D[] = [];
    private _listObj:Item[] = [];
    protected onInit(){
        this._texture2d = [];
        App.Res.loadResources('img/red_point_0',cc.Texture2D,(t2d:cc.Texture2D)=>{
            this._texture2d.push(t2d);
        });
        App.Res.loadResources('img/red_point_1',cc.Texture2D,(t2d:cc.Texture2D)=>{
            this._texture2d.push(t2d);
        });
    }

    protected onDestroy(){
        this._texture2d = null;
        this._listObj = [];
    }
    /**
     * 
     * @param parent 挂接红点的节点对象
     * @param pos 红点展示位置
     * @param type 红点类型
     * @param scale 红点缩放
     * @param bindProtol 绑定事件
     * @returns 
     */
    public register(parent:cc.Node|cc.Component,pos:cc.Vec2 = cc.v2(0,0),type:RedPointType=RedPointType.default,bindProtol:string[] = []){
        if (App.Util.isInvalid(parent)) return ;

        if (parent instanceof cc.Component){
            parent = parent.node;
            for (let it of this._listObj){
                if (it.target === parent){
                    return ;
                }
            }
        }

        const sub:Item = {target:parent,redImg:null,lblNum:null,redType:type,bindProtol:bindProtol};
        const red:cc.Node = (new cc.Node(`${parent.name}_red`));
        red.addComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(this._texture2d[type]);
        red.active = false;
        //red.scale = scale;
        red.setAnchorPoint(cc.v2(0.5,0.5));
        red.setPosition(pos);
        parent.addChild(red);
        sub.redImg = red;
        if (type === RedPointType.number){
            sub.lblNum = (new cc.Node(`${parent.name}_red_lbl`)).addComponent(cc.Label);
            sub.lblNum.fontSize = 30;
            sub.lblNum.node.setAnchorPoint(cc.v2(0.5,0.5));
            sub.lblNum.node.setPosition(cc.v2(0,-10));
            sub.lblNum.node.parent = red;
        }
        this._listObj.push(sub);
    }

    /**
     * 注销红点
     * @param parent 红点父节点
     * @returns 
     */
    public unregister(target:cc.Node|cc.Component){
        if (App.Util.isInvalid(target)) return ;
        target instanceof cc.Component && (target = target.node);
        this._listObj.forEach((it:Item,idx:number)=>{
            if (it.target === target){
                this._listObj.splice(idx,1);
                return ;
            }
        });
    }

    /**
     * UI层点击节点
     * @param target 点击节点对象，即红点的父节点 
     * @param active 显示或隐藏
     * @param num 红点上展示数字
     * @returns 
     */
    public touchTarget(target:cc.Node|cc.Component,active:boolean,num:number = 0){
        if (App.Util.isInvalid(target)) return ;
        target instanceof cc.Component && (target = target.node);
        this._listObj.forEach((it:Item)=>{
            if (it.target === target){
                it.redImg.active = it.redType === RedPointType.default ? active:num>0;
                if (active && App.Util.isValid(it.lblNum) && it.redType === RedPointType.number){
                    it.lblNum.string = num > 0 ? `${num}`:'';
                }
            }
        });
    }

    /**
     * 更新通知打开/关闭红点，更新红点上的文本
     * @param protol 协议 RedPointEvent
     * @param active 显示/隐藏
     * @param num 红点上展示数字
     * @returns 
     */
    public notify(protol:string,active:boolean,num:number = 0){
        if (App.Util.isEmpty(protol)) return ;
        
        for (let obj of this._listObj){
            if (obj.bindProtol.indexOf(protol) > -1){
                if (active && obj.lblNum){
                    obj.redImg.active = num > 0;
                    obj.lblNum.string = num > 0 ? `${num}` : '';
                } else obj.redImg.active = active;
            }
        }
    }
}

const RedPointSys:CRedPointSys = CRedPointSys.getInstance<CRedPointSys>(CRedPointSys);
export default RedPointSys;